Planet Python
Last update: December 05, 2025 04:43 PM UTC
December 05, 2025
Real Python
The Real Python Podcast – Episode #276: Exploring Quantum Computing & Python Frameworks
What are the recent advances in the field of quantum computing and high-performance computing? And what Python tools can you use to develop programs that run on quantum computers? This week on the show, Real Python author Negar Vahid discusses her tutorial, "Quantum Computing Basics With Qiskit."
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 05, 2025 12:00 PM UTC
Mark Dufour
Shed Skin restricted-Python-to-C++ compiler v0.9.11
I have just released version 0.9.11 of Shed Skin, a restricted-Python-to-C++ compiler. Most importantly, it adds support for Python 3.14. It also adds support for many 3.x features that were not yet implemented, in addition to basic support for the base64 module. It also optimizes a few more common code patterns.
Paul Boddie was able to add support for libpcre2, and in the process updated conan to version 2. Thanks to Shakeeb and now Paul, Shed Skin has had first-class Windows support for the last few releases.
A new release is often triggered by a nice new example. In this case I found an advanced/educational 3d renderer by Benny Bobaganoosh, and rewrote it from Java to Python. In ~500 lines of code, it renders an .obj file with perspective-correct texture mapping and so on, clipping, lighting.. It becomes about 13 times faster after compilation (in other words, it goes from about 2 to about 30 FPS).
For the full list of changes in the release, please see the release notes.
Something I have noticed while working on this release is that small object allocations seem to have become faster under Linux, to the degree that programs that would become _slower_ after compilation because of excessive small-object allocation, are now usually _faster_ again, at least on my system. This motivated me to measure the speedup for all 84 example programs at the moment versus cpython 3.13. While it's still all over the place, I was happy to see a median speedup of 12 times, and an average of 20 times.
I would very much appreciate more feedback on/assistance with the project. There is always enough low-hanging fruit to help with! See for example the current list of issues for 0.9.12. But just testing random things, finding interesting new example programs, cleaning up parts of the code and such are also much appreciated.
December 05, 2025 03:08 AM UTC
December 03, 2025
Caktus Consulting Group
LLM Basics: Ollama Function Calling
In our previous post, we introduced function calling and learned how to do it with OpenAI’s LLMs.
In this post, we’ll call the same cactify_name function from that post using Meta’s
Llama 3.2 model, installed locally using Ollama. The techniques in this post should also work
with other Ollama models that support function-calling.
December 03, 2025 04:42 PM UTC
Real Python
How to Use Google's Gemini CLI for AI Code Assistance
This tutorial will teach you how to use Gemini CLI to bring Google’s AI-powered coding assistance directly into your terminal. After you authenticate with your Google account, this tool will be ready to help you analyze code, identify bugs, and suggest fixes—all without leaving your familiar development environment:
Gemini CLIImagine debugging code without switching between your console and browser, or picture getting instant explanations for unfamiliar projects. Like other command-line AI assistants, Google’s Gemini CLI brings AI-powered coding assistance directly into your command line, allowing you to stay focused in your development workflow.
Whether you’re troubleshooting a stubborn bug, understanding legacy code, or generating documentation, this tool acts as an intelligent pair-programming partner that understands your codebase’s context.
You’re about to install Gemini CLI, authenticate with Google’s free tier, and put it to work on an actual Python project. You’ll discover how natural language queries can help you understand code faster and catch bugs that might slip past manual review.
Prerequisites
To follow along with this tutorial, you’ll need the following:
- Google Account: A personal Google account is required to use Gemini CLI’s free tier, which offers one thousand requests per day and sixty requests per minute at no charge.
- Python 3.12 or Higher: You’ll work with a Python command-line application to demonstrate Gemini CLI’s capabilities. If you haven’t already, install Python on your system, making sure the minimum version is Python 3.12.
- Node.js 20 or Higher: Gemini CLI is distributed through npm, Node.js’s package manager. You’ll verify your Node.js installation in the next section.
Because Gemini CLI is a command-line tool, you should feel comfortable navigating your terminal and running basic shell commands.
Go ahead and download the supporting materials to get the Python project you’ll be working with throughout this tutorial:
Get Your Code: Click here to download the free sample code that you’ll use to take Google’s Gemini CLI for a spin.
Once you’ve extracted the files, you’ll find a todolist/ directory containing a complete Python CLI application, which is similar to the to-do app covered in another tutorial. This project will serve as your testing ground for Gemini CLI’s code analysis and debugging features.
Take the Quiz: Test your knowledge with our interactive “How to Use Google's Gemini CLI for AI Code Assistance” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
How to Use Google's Gemini CLI for AI Code AssistanceLearn how to install, authenticate, and safely use the Gemini CLI to interact with Google's Gemini models.
Step 1: Install and Set Up Gemini CLI
Before you can start using the AI-powered features of Gemini CLI, you need to get it installed on your system and authenticate with Google. In this step, you’ll verify your Node.js installation, install Gemini CLI globally, and complete the authentication process to access the free tier.
Verify Your Node.js Installation
Gemini CLI is primarily implemented in TypeScript, which requires Node.js. You’ll need Node.js version 20 or higher to run Gemini CLI. First, check if you have Node.js installed in the required version by opening your terminal and running this command:
$ node --version
v24.11.1
If you see a version number of 20 or higher, then you’re all set. Otherwise, if you encounter a command not found error or have an older version, then you’ll need to install or update Node.js before continuing.
Note: If you’re on macOS or Linux, then you can leverage Homebrew to get Gemini CLI without having to install Node.js yourself.
The recommended approach to install Node.js is to use the Node Version Manager (nvm), which allows you to install and switch between multiple Node.js versions, much like pyenv does for Python. You can find detailed installation instructions for your operating system on the Node.js download page.
Once Node.js is installed, you’ll also have access to the Node Package Manager (npm), which you’ll use in the next step.
Install Gemini CLI Globally
With Node.js installed, you can now install Gemini CLI using npm. The -g flag installs the package globally, making the gemini command available from anywhere in your file system:
$ npm install -g @google/gemini-cli
Read the full article at https://realpython.com/how-to-use-gemini-cli/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 03, 2025 02:00 PM UTC
Django Weblog
Django 6.0 released
The Django team is happy to announce the release of Django 6.0.
The release notes assembles a mosaic of modern tools and thoughtful design. A few highlights are:
- Template Partials: modularize templates using small, named fragments for cleaner, more maintainable code. (GSoC project by Farhan Ali Raza, mentored by Carlton Gibson)
- Background Tasks: run code outside the HTTP request-response cycle with a built-in, flexible task framework. (Jake Howard)
- Content Security Policy (CSP): easily configure and enforce browser-level security policies to protect against content injection. (Rob Hudson)
- Modernized Email API: compose and send emails with Python's EmailMessage class for a cleaner, Unicode-friendly interface. (Mike Edmunds)
You can get Django 6.0 from our downloads page or from the Python Package Index.
The PGP key ID used for this release is Natalia Bidart: 2EE82A8D9470983E
With the release of Django 6.0, Django 5.2 has reached the end of mainstream support. The final minor bug fix release, 5.2.9, was issued yesterday. Django 5.2 will receive security and data loss fixes until April 2028. All users are encouraged to upgrade before then to continue receiving fixes for security issues.
Django 5.1 has reached the end of extended support. The final security release, 5.1.15, was issued on Dec. 2, 2025. All Django 5.1 users are encouraged to upgrade to a supported Django version.
See the downloads page for a table of supported versions and the future release schedule.
December 03, 2025 12:00 PM UTC
Real Python
Quiz: How to Use Google's Gemini CLI for AI Code Assistance
In this quiz, you’ll test your understanding of the How to Use Google’s Gemini CLI for AI Code Assistance tutorial.
By working through these questions, you’ll revisit how to install and verify prerequisites like Node.js, explore authentication options, and understand the CLI’s permission and safety model. You’ll also practice managing interactive sessions, enforcing stronger models, and approving or editing shell commands securely.
To deepen your understanding, review the sections on verifying your environment, authenticating safely, and running interactive prompts in the linked tutorial.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 03, 2025 12:00 PM UTC
Talk Python to Me
#529: Computer Science from Scratch
A lot of people building software today never took the traditional CS path. They arrived through curiosity, a job that needed automating, or a late-night itch to make something work. This week, David Kopec joins me to talk about rebuilding computer science for exactly those folks, the ones who learned to program first and are now ready to understand the deeper ideas that power the tools they use every day.<br/> <br/> <strong>Episode sponsors</strong><br/> <br/> <a href='https://talkpython.fm/sentry'>Sentry Error Monitoring, Code TALKPYTHON</a><br> <a href='https://talkpython.fm/nordstellar'>NordStellar</a><br> <a href='https://talkpython.fm/training'>Talk Python Courses</a><br/> <br/> <h2 class="links-heading mb-4">Links from the show</h2> <div><strong>David Kopec</strong>: <a href="https://davekopec.com?featured_on=talkpython" target="_blank" >davekopec.com</a><br/> <strong>Classic Computer Science Book</strong>: <a href="https://www.amazon.com/Classic-Computer-Science-Problems-Python/dp/1617295981?featured_on=talkpython" target="_blank" >amazon.com</a><br/> <strong>Computer Science from Scratch Book</strong>: <a href="https://computersciencefromscratch.com?featured_on=talkpython" target="_blank" >computersciencefromscratch.com</a><br/> <strong>Computer Science from Scratch at NoStartch (CSFS30 for 30% off)</strong>: <a href="https://nostarch.com/computer-science-from-scratch?featured_on=talkpython" target="_blank" >nostarch.com</a><br/> <br/> <strong>Watch this episode on YouTube</strong>: <a href="https://www.youtube.com/watch?v=EVQOoD6cZmg" target="_blank" >youtube.com</a><br/> <strong>Episode #529 deep-dive</strong>: <a href="https://talkpython.fm/episodes/show/529/computer-science-from-scratch#takeaways-anchor" target="_blank" >talkpython.fm/529</a><br/> <strong>Episode transcripts</strong>: <a href="https://talkpython.fm/episodes/transcript/529/computer-science-from-scratch" target="_blank" >talkpython.fm</a><br/> <br/> <strong>Theme Song: Developer Rap</strong><br/> <strong>🥁 Served in a Flask 🎸</strong>: <a href="https://talkpython.fm/flasksong" target="_blank" >talkpython.fm/flasksong</a><br/> <br/> <strong>---== Don't be a stranger ==---</strong><br/> <strong>YouTube</strong>: <a href="https://talkpython.fm/youtube" target="_blank" ><i class="fa-brands fa-youtube"></i> youtube.com/@talkpython</a><br/> <br/> <strong>Bluesky</strong>: <a href="https://bsky.app/profile/talkpython.fm" target="_blank" >@talkpython.fm</a><br/> <strong>Mastodon</strong>: <a href="https://fosstodon.org/web/@talkpython" target="_blank" ><i class="fa-brands fa-mastodon"></i> @talkpython@fosstodon.org</a><br/> <strong>X.com</strong>: <a href="https://x.com/talkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @talkpython</a><br/> <br/> <strong>Michael on Bluesky</strong>: <a href="https://bsky.app/profile/mkennedy.codes?featured_on=talkpython" target="_blank" >@mkennedy.codes</a><br/> <strong>Michael on Mastodon</strong>: <a href="https://fosstodon.org/web/@mkennedy" target="_blank" ><i class="fa-brands fa-mastodon"></i> @mkennedy@fosstodon.org</a><br/> <strong>Michael on X.com</strong>: <a href="https://x.com/mkennedy?featured_on=talkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @mkennedy</a><br/></div>
December 03, 2025 08:00 AM UTC
December 02, 2025
Christian Ledermann
Game development with SpecKit, Rust and Bevy
brkrs — a fun, playable brick-breaker game & learning playground
brkrs is a real, playable Breakout/Arkanoid-style game written in Rust 🦀 using the Bevy engine.
It’s also a hands-on learning project, letting you explore:
- Spec-first development with GitHub speckit
- Incremental feature development through issues & PRs
- AI-assisted and agentic coding experiments
Every feature starts as a spec, flows through an issue or PR, and ends as working Rust code. You can play the game, explore the code, and learn modern Rust/Bevy workflows all at the same time.
Linus Torvalds said: “Talk is cheap. Show me the code.”
brkrs lets you play, tinker, and see the specs come alive in a real game.
The Story Behind brkrs
I always wanted to rewrite my old Arkanoid/Breakout-style game, YaAC 🐧, in a modern game framework.
I began by manually implementing the core gameplay foundations: reading documentation, following examples, and building a basic proof-of-concept with the essential mechanics (ball, paddle, bricks).
It quickly became clear that doing everything manually would involve a steep learning curve and a lot of time.
brkrs was born as a solution: a way to learn modern Rust game development, apply spec-first workflows, and experiment with AI-assisted coding, all while still having fun playing a real game.
Try it now
You can play a web version on GitHub Pages
Key Features
brkrs is a Breakout/Arkanoid style game implemented in Rust with the Bevy engine. It extends the classic formula with richer physics, paddle rotation, and per-level configuration.
- Classic Breakout-style gameplay: paddle, ball, bricks, and levels
- Levels are human-readable and easy to modify
- Spec-first workflow: every feature begins as a spec and ends as working Rust code
- Small, incremental PRs demonstrate the development workflow and learning path
- Crate-ready and cross-platform (desktop + WebAssembly builds)
- A fun, approachable way to learn Rust, Bevy, and modern coding practices
Quickstart (play & learn)
Prerequisites: Rust + Cargo + Git
git clone https://github.com/cleder/brkrs.git
cd brkrs
cargo run --release
Controls: move paddle with mouse, scroll wheel to rotate (if enabled), ESC to pause.
Play, tweak, and learn — modify levels, bricks, or mechanics to see specs turn into features.
Core Systems
- Physics (Rapier3D) – 3D physics constrained to a flat play plane.
- Game State – (planned) menu, playing, paused, game over, transitions.
- Level Loader – RON file parsing, entity spawning, per-level gravity.
- Brick System – Extensible brick behaviors via components & events.
- Pause System – ESC to pause, click to resume, with window mode switching (native).
Learning Path & Contribution
This project is intended to be fun and educational. Suggested learning steps:
- Read a spec in the repo or wiki
- Pick a small issue to implement
- Submit a PR that fulfills the spec
- Experiment with AI-assisted features or gameplay tweaks
Documentation
Full documentation is available at brkrs.readthedocs.io:
- Quickstart Guide — Get running in 10 minutes
- Developer Guide — Set up a development environment
- API Reference — Rust API documentation
Why You’ll Enjoy It
- Play a real game while learning coding practices
- Watch specs transform into working features
- Experiment safely with Rust, Bevy, and AI-assisted workflows
- Learn by doing in a hands-on, playful way
December 02, 2025 10:00 PM UTC
PyCoder’s Weekly
Issue #711: pairwise(), Mocks, Claude, and More (Dec. 2, 2025)
#711 – DECEMBER 2, 2025
View in Browser »
Generalising itertools.pairwise
This article teaches you about itertools.pairwise, a function for accessing pairs of components over an iterable. Learn where it is helpful and what its limitations are.
RODRIGO GIRÃO SERRÃO
Why Your Mock Breaks Later
An overly aggressive mock can work fine, but then break much later. If you don’t mock the right spot in your code you can break other testing libraries.
NED BATCHELDER
Turn Multi-Agent Mayhem into Harmony (with Python + Temporal)
AI is powerful but messier than a three-way Git merge on a Friday afternoon. Join us to see how Temporal helps Python devs orchestrate multi-agent systems with confidence. Learn how to make your agents play nicely and your code stay clean →
TEMPORAL sponsor
Getting Started With Claude Code
Learn to set up and use Claude Code for Python projects: install, run commands, and integrate with Git.
REAL PYTHON course
PyCon Austria 2026: Free Conference, Registration Is Open
PYCON.AT • Shared by Horst JENS
Microsoft Announces SQL Server Python Driver
MICROSOFT.COM • Shared by Howard Rothenburg
Python Jobs
Python Video Course Instructor (Anywhere)
Python Tutorial Writer (Anywhere)
Articles & Tutorials
PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats
There is an attack on-going in the JavaScript/NPM world that has been named Shai-Hulud. It has targeted a large number of packages. So far, PyPI has not been exploited, but attempts have been made. This post explains what the folks at PyPI are doing to prevent problems and how you can protect yourself.
MIKE FIEDLER
Understanding the Different POST Content Types
When writing code that accepts user data on the web, you usually are using the HTTP POST method. POST supports several different types of data in the request body. This post teaches you about each of them, with examples in Django to make it clearer.
AIDAS BENDORAITIS
B2B Authentication for any Situation - Fully Managed or BYO
What your sales team needs to close deals: multi-tenancy, SAML, SSO, SCIM provisioning, passkeys…What you’d rather be doing: almost anything else. PropelAuth does it all for you, at every stage →
PROPELAUTH sponsor
American Data Centers
This step-by-step post shows you how to do data analysis on the Business Insider’s dataset on American Data Centres. The analysis uses a variety of tools, including the Python esprima library for parsing, duckdb, and more.
MARK LITWINTSCHIK
Django: Implement HTTP Bearer Authentication
HTTP Bearer is a header-based mechanism authentication mechanism. There are many Django frameworks that support it, but some can be a little heavy weight. Learn how to handle HTTP Bearer Authentication in your own code.
ADAM JOHNSON
Pydantic Can Do What?
Pydantic started out as a validation library but over the years it has added many useful features. It includes a full-featured settings loader which can read from multiple env files, config files, and cloud vaults.
BITE CODE!
Why Django’s DATETIME_FORMAT Ignores You
A dive into why Django’s DATETIME_FORMAT setting seems to do nothing, and how to actually force the 24-hour clock in the admin, even when your locale says otherwise.
KEVIN RENSKERS
Disable Network Requests When Running pytest
Even with diligent mocking of external requests, a few web requests can still slip through. A quick pytest fixture can force a failure though, saving you from problems.
ANŽE PEČAR
How to Properly Indent Python Code
Learn how to properly indent Python code in IDEs, Python-aware editors, and plain text editors—plus explore PEP 8 formatters like Black and Ruff.
REAL PYTHON
Why Developers Still Flock to Python
This interview with Python creator Guido van Rossum covers everything from writing readable code to AI and the future of programming.
NATALIE GUEVARA
Your new AI Pair Programmer for Data Science
Most AI coding assistants are built for general software engineering. Positron’s AI is different. It’s designed to work with you, not replace you, while understanding your data science workflow
POSIT sponsor
Improve Your Programming Skills With Advent of Code
It is that time of year again, time for Advent of Code. Not familiar? This post explains what it is and how it can help you up-skill.
JUHA-MATTI SANTALA
How to Convert Bytes to Strings in Python
Turn Python bytes to strings, pick the right encoding, and validate results with clear error handling strategies.
REAL PYTHON
Projects & Code
elf: Advent of Code Helper for Python
GITHUB.COM/CAK • Shared by Caleb Kinney
Minimalist, Thread-Safe Config Management for Python
GITHUB.COM/POMPONCHIK • Shared by Evgeniy Blinov
Events
Weekly Real Python Office Hours Q&A (Virtual)
December 3, 2025
REALPYTHON.COM
Canberra Python Meetup
December 4, 2025
MEETUP.COM
Sydney Python User Group (SyPy)
December 4, 2025
SYPY.ORG
PyData Global 2025
December 9 to December 12, 2025
PYDATA.ORG
PiterPy Meetup
December 9, 2025
PITERPY.COM
Leipzig Python User Group Meeting
December 9, 2025
MEETUP.COM
Happy Pythoning!
This was PyCoder’s Weekly Issue #711.
View in Browser »
[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
December 02, 2025 07:30 PM UTC
Python Morsels
Wrapping text output in Python
Python's textwrap module includes utilities for wrapping text to a maximum line length.
Improving readability with text wrapping
Sometimes programmers like to manually wrap their text to a specific maximum line length.
This is unwrapped free-flowing text (made with a multiline string):
license = """
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
""".strip()
print(license)
When we print this text at the terminal, it will something like this:
$ python3 license.py
Permission is hereby granted, free of charge, to any person obtaining a copy of this softwar
e and associated documentation files (the "Software"), to deal in the Software without restr
iction, including without limitation the rights to use, copy, modify, merge, publish, distri
bute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Soft
ware is furnished to do so, subject to the following conditions:
Let's manually wrap this text to a 78-character line length:
license = """
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
""".strip()
print(license)
When we print this text, we'll now see that it's a bit easier to read in our terminal:
$ python3 license.py
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
How can we do this text wrapping automatically?
Wrapping text to a fixed width with textwrap.wrap
Python's textwrap module has a …
Read the full article: https://www.pythonmorsels.com/wrapping-text/
December 02, 2025 04:00 PM UTC
Nicola Iarocci
Eve 2.2.4
Eve v2.2.4 was just released on PyPI. It is a minor update, with a validation fix contributed by smeng9. See the changelog for details.
December 02, 2025 03:06 PM UTC
Real Python
Introduction to pandas
The pandas DataFrame is a structure that contains two-dimensional data and its corresponding labels. DataFrames are widely used in data science, machine learning, scientific computing, and many other data-intensive fields.
DataFrames are similar to SQL tables or the spreadsheets that you work with in Excel or Calc. In many cases, DataFrames are faster, easier to use, and more powerful than tables or spreadsheets because they’re an integral part of the Python and NumPy ecosystems.
In this video course, you’ll learn:
- What a pandas DataFrame is and how to create one
- How to access, modify, add, sort, filter, and delete data
- How to handle missing values
- How to work with time-series data
- How to quickly visualize data
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 02, 2025 02:00 PM UTC
Django Weblog
Django security releases issued: 5.2.9, 5.1.15, and 4.2.27
In accordance with our security release policy, the Django team is issuing releases for Django 5.2.9, Django 5.1.15, and Django 4.2.27. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.
CVE-2025-13372: Potential SQL injection in FilteredRelation column aliases on PostgreSQL
FilteredRelation was subject to SQL injection in column aliases, using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed to QuerySet.annotate() or QuerySet.alias() on PostgreSQL.
Thanks to Stackered for the report.
This issue has severity "high" according to the Django security policy.
CVE-2025-64460: Potential denial-of-service vulnerability in XML serializer text extraction
Algorithmic complexity in django.core.serializers.xml_serializer.getInnerText() allowed a remote attacker to cause a potential denial-of-service triggering CPU and memory exhaustion via specially crafted XML input submitted to a service that invokes XML Deserializer. The vulnerability resulted from repeated string concatenation while recursively collecting text nodes, which produced superlinear computation resulting in service degradation or outage.
Thanks to Seokchan Yoon (https://ch4n3.kr/) for the report.
This issue has severity "moderate" according to the Django security policy.
Affected supported versions
- Django main
- Django 6.0 (currently at release candidate status)
- Django 5.2
- Django 5.1
- Django 4.2
Resolution
Patches to resolve the issue have been applied to Django's main, 6.0 (currently at release candidate status), 5.2, 5.1, and 4.2 branches. The patches may be obtained from the following changesets.
CVE-2025-13372: Potential SQL injection in FilteredRelation column aliases on PostgreSQL
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 5.1 branch
- On the 4.2 branch
CVE-2025-64460: Potential denial-of-service vulnerability in XML serializer text extraction
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 5.1 branch
- On the 4.2 branch
The following releases have been issued
- Django 5.2.9 (download Django 5.2.9 | 5.2.9 checksums)
- Django 5.1.15 (download Django 5.1.15 | 5.1.15 checksums)
- Django 4.2.27 (download Django 4.2.27 | 4.2.27 checksums)
The PGP key ID used for this release is Natalia Bidart: 2EE82A8D9470983E
General notes regarding security reporting
As always, we ask that potential security issues be reported via private email to security@djangoproject.com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.
December 02, 2025 12:00 PM UTC
Python Software Foundation
Sovereign Tech Agency and PSF Security Partnership
We are thrilled to announce that the Sovereign Tech Agency has committed to a €86,000 investment in work to be performed by the Python Software Foundation to improve the security of CPython and the Python Package Index (PyPI). The Sovereign Tech Agency is a public organization in Germany that focuses on increasing the security and resilience of critical open source software that forms the foundation of modern digital technology.
December 02, 2025 07:00 AM UTC
December 01, 2025
Mike Driscoll
ANN: Vibe Coding Video Games with Python
I am happy to announce my latest book, Vibe Coding Video Games with Python. Here’s the announcement from my Kickstarter:
Welcome to Vibe Coding Video Games with Python. In this book, you will learn how to use artificial intelligence to create mini-games. You will attempt to recreate the look and feel of various classic video games. The intention is not to violate copyright or anything of the sort, but instead to learn the limitations and the power of AI.
Instead, you will simply be learning about whether or not you can use AI to help you know how to create video games. Can you do it with no previous knowledge, as the AI proponents say? Is it really possible to create something just by writing out questions to the ether?
Release date: January 2026 (eBook) / March 2026 (paperback)
You will be using various large language models (LLMs) such as Google Gemini, Grok, Mistral, CoPilot, and others to create these games. You will discover the differences and similarities between these tools. You may be surprised to find that some tools give much more context than others.
AI is certainly not a cure-all and is far from perfect. You will quickly discover AI’s limitations and learn some strategies for solving those kinds of issues.

Here are some examples of what you will be creating in this book:
Lune Lander Clone

Asteroids Clone

Pong Clone

What You’ll Learn
You’ll be creating “clones” of some popular games. However, these games will only be the first level and may or may not be fully functional.
- Chapter 1 – The Snake Game
- Chapter 2 – Pong Clone
- Chapter 3 – Frogger Clone
- Chapter 4 – Space Invaders Clone
- Chapter 5 – Minesweeper Clone
- Chapter 6 – Luna Lander Clone
- Chapter 7 – Asteroids Clone
- Chapter 8 – Tic-Tac-Toe
- Chapter 9 – Pole Position Clone
- Chapter 10 – Connect Four
- Chapter 11 – Intro to Sprites
Rewards to Choose From
There are several different rewards you can get in this Kickstarter:
- A signed paperback copy of the book
- An eBook copy of the book in PDF and ePub
- A t-shirt with the cover art from the book
- Other Python eBooks
Support the Kickstarter Today
The post ANN: Vibe Coding Video Games with Python appeared first on Mouse Vs Python.
December 01, 2025 04:11 PM UTC
Caktus Consulting Group
LLM Basics: OpenAI Function Calling
In our previous post, we explored how to send text to an LLM and receive a text response in return. That is useful for chatbots, but often we need to integrate LLMs with other systems. We may want the model to query a database, call an external API, or perform calculations.
December 01, 2025 03:00 PM UTC
Real Python
Quantum Computing Basics With Qiskit
Every classical computer reduces the world to 0s and 1s. That binary framework has carried us from calculators to supercomputers, but some problems demand checking through 2n possibilities, a task that outpaces even the best machines. Now, what if information could exist in many states at once? That what if turned into a new model called quantum computation. Keep reading to break with binaries and get an overview of quantum computing basics.
By the end of this tutorial, you’ll understand that:
- Qubits, or quantum bits, are the basic units of quantum computing.
- A qubit can be in a superposition of 0 and 1. This means its state is a precise combination of both until measurement forces it to become either 0 or 1.
- The Bloch sphere is a standard way to visualize what a single qubit is doing.
- Entanglement creates strong correlations between two or more qubits, so measuring one tells you something about the others that you can’t explain with classical reasoning alone.
- Interference adjusts probability amplitudes so that wrong outcomes cancel and useful outcomes reinforce.
- Quantum hardware comes in different architectures, each with its own strengths and limitations.
- With Python libraries like Qiskit, you can build and run quantum circuits directly from Python.
Before you jump in, it’d be a good idea to go through the basics of classical computing. For example, knowing how bits work, what logic gates like AND and NOT do, and how you can determine the runtime complexity of an algorithm using Big O notation will help you understand the differences and advantages of quantum computing.
Get Your Code: Click here to download the free sample code to build a quantum circuit with Qiskit.
Take the Quiz: Test your knowledge with our interactive “Quantum Computing Basics With Qiskit” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Quantum Computing Basics With QiskitTest your understanding of quantum computing basics, including superposition, qubits, entanglement, and key programming concepts.
Introduction to Quantum Computing
Quantum computing is the use of fundamental ideas from quantum mechanics to perform computations on special devices called quantum computers. Quantum systems can process information in ways that classical computers can’t. For example, they can explore multiple possibilities at once. This capability is thanks to concepts like superposition, entanglement, and interference, which you’ll explore soon.
To see how quantum computing works, it helps to look at the main quantum concepts in the context of computing and consider how they differ from classical approaches. You’ll cover these essential concepts in this tutorial.
Before moving on, keep in mind that quantum mechanics and quantum computing are often counterintuitive because they occur only at very small scales and not in everyday life. Even Niels Bohr, one of the founders of quantum theory, once said:
If quantum mechanics hasn’t profoundly shocked you, you haven’t understood it yet. (Source)
— Niels Bohr
Until recently, quantum computing was seen almost entirely as a physics domain, which kept people in other fields from applying it to their own work. The good news is that you don’t need to fully grasp the physics to understand how quantum computers can solve some problems more efficiently than classical ones. You can focus on the concepts and their implementation, and only later dive into the math if you want a deeper understanding.
To start, you’ll look at the basic unit of quantum information—quantum bits, or qubits—and learn how they differ from classical bits.
Qubits, Superposition, and Measurement
Qubits, or quantum bits, are the fundamental units of quantum information. A classical bit can only be 0 or 1, but a qubit can exist in a linear combination of both states at once, a property called superposition. Physically, this usually means that the qubit is a two-level system, such as two energy levels of an atom, that can exist in a superposition of those levels.
Superposition allows qubits to represent multiple possibilities at the same time, allowing quantum computing programs to explore many solutions in parallel.
To understand superposition, think of flipping a coin. A classical coin lands as either heads or tails. A quantum coin, however, can exist in a state that’s a blend of both heads and tails simultaneously. This is what physicists mean when they say a qubit exists in a linear combination of 0 and 1.
The key difference is that while the coin is spinning in the air, you know it’ll eventually be one or zero, whereas a qubit in superposition has no definite value until it is measured.
A qubit remains in superposition until you look at it, or more formally, measure it. Measurement forces the qubit to collapse into one of its basis states, 0 or 1, just like your usual classical bits. The outcome is probabilistic: You can’t know in advance which result you’ll get, but you can calculate the chances based on the qubit’s state beforehand.
Note: Looking at a superposition state actually destroys the superposition and collapses the qubit into a 0 or 1, or in other words, destroys the “quantumness” of the state. This means you can’t visualize qubits like bits. Instead, you view qubits as a mathematical object. However, they can be built from various physical systems: the spin of an electron, the polarization of a photon, or the energy levels of an atom.
Visualizing qubits and superposition is tricky and needs some extra mathematical tools. Turns out, a coin that’s free to rotate in three dimensions is a good analogy for one way of visualizing the quantum state of a qubit, called the Bloch Sphere.
The Bloch sphere is a geometrical, 3D sphere that’s often used to visualize qubits and their superpositions. The states of the qubits, including superpositions, are represented as points on the surface of a sphere. The closer the point is to the north pole, the higher the chance of measuring 0, and vice versa for 1:
Two Bloch spheres showing a qubit in the 0 (left) state and a qubit in the 1 state (right)
For example, the north pole represents the state 0, and the south pole represents 1. What’s interesting about this sphere is that you can visualize superposition states as well:
A Bloch sphere showing a qubit in a superposition state.
Read the full article at https://realpython.com/quantum-computing-basics/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 01, 2025 02:00 PM UTC
death and gravity
reader 3.20 released – we're so back
Hi there!
I'm happy to announce version 3.20 of reader, a Python feed reader library.
What's new? #
Here are the highlights since reader 3.16.
Web app re-design #
Earlier this year, I started a web app re-design based on htmx and Bootstrap. I only had time for the main page, but it turned out pretty nice, and I've been using it ever since. What is new is that I now have free time and some plans; watch this space.
Here are some screenshots; it's not much, but it's honest work:
main page (dark mode)
main page – more filters (light mode)
htmx? ugh, how original
Unsurprisingly, htmx is perfect for this kind of application. As CEO of htmx, I can confirm that all the allegations are true – it is indeed a pleasure to use, not to mention a huge improvement over my home-grown, half-assed JavaScript forms framework.
isn't Bootstrap from like 2010 or something? also, how original
I've tried many modern popular CSS frameworks (since forgotten, for my own sanity), and it turns out tab-navigable form controls are a hard, unsolved problem in 2025. Thankfully, if you're willing to time travel (to the future, surely!), Bootstrap comes with excellent documentation, built-in accessibility, and a comprehensive component library.
Entry deduplication #
I may have accidentally rewritten the entry_dedupe plugin. 😅
Sometimes, the id of some or all the entries in a feed changes (e.g. from
example.com/123toexample.com/entry-title), causing each entry to appear twice. entry_dedupe fixes this by copying user attributes to the new entry and deleting the old one.
What started as a quick and dirty plugin now has:
- lots of new, data-driven heuristics to find potential duplicates
- by title (had this one already)
- by link
- by published timestamp
- by title with common prefixes removed
- better approximate content matching
- an extensive test suite
- extensive internal documentation (like this)
That last one is pretty important: the old logic was data-driven too, but because I didn't document my entire reasoning, I wasted more time than I'd like to admit on a useless title similarity heuristic. It's a trope that you should write code such that others can understand it, and "others" includes you six months from now; I don't know about six months, but four years will definitely do it. (If that sounds like an interesting story and you'd like to hear more, drop me a line.)
It's not all bad, though –
a side-effect of better content matching
is that image alt and title attributes
are also included in the full-text search index now,
so you can search xkcd comics by title text.
Project infrastructure #
I've taken some time to modernize the project infrastructure; stuff like:
- Use GitHub Actions to publish releases to PyPI.
- Use dependency groups instead of extras for development dependencies.
- Rewrite contributor documentation and run.sh to optimize for readability.
(I'll admit the uv hype is quite strong, but the vanilla tooling seems fine, for now.)
Read-only Reader #
It's now possible to prevent write operations on a Reader object
through the read_only make_reader() argument.
Thanks to Roman Milko for the pull request!
Python versions #
reader 3.17 added support for PyPy 3.11.
reader 3.18 dropped support for Python 3.10.
reader 3.19 added support for Python 3.14.
That's it for now. For more details, see the full changelog.
Want to contribute? Check out the docs and the roadmap.
Learned something new today? Share it with others, it really helps!
What is reader? #
reader takes care of the core functionality required by a feed reader, so you can focus on what makes yours different.
reader allows you to:
- retrieve, store, and manage Atom, RSS, and JSON feeds
- mark articles as read or important
- add arbitrary tags/metadata to feeds and articles
- filter feeds and articles
- full-text search articles
- get statistics on feed and user activity
- write plugins to extend its functionality
...all these with:
- a stable, clearly documented API
- excellent test coverage
- fully typed Python
To find out more, check out the GitHub repo and the docs, or give the tutorial a try.
Why use a feed reader library? #
Have you been unhappy with existing feed readers and wanted to make your own, but:
- never knew where to start?
- it seemed like too much work?
- you don't like writing backend code?
Are you already working with feedparser, but:
- want an easier way to store, filter, sort and search feeds and entries?
- want to get back type-annotated objects instead of dicts?
- want to restrict or deny file-system access?
- want to change the way feeds are retrieved by using Requests?
- want to also support JSON Feed?
- want to support custom information sources?
... while still supporting all the feed types feedparser does?
If you answered yes to any of the above, reader can help.
The reader philosophy #
- reader is a library
- reader is for the long term
- reader is extensible
- reader is stable (within reason)
- reader is simple to use; API matters
- reader features work well together
- reader is tested
- reader is documented
- reader has minimal dependencies
Why make your own feed reader? #
So you can:
- have full control over your data
- control what features it has or doesn't have
- decide how much you pay for it
- make sure it doesn't get closed while you're still using it
- really, it's easier than you think
Obviously, this may not be your cup of tea, but if it is, reader can help.
December 01, 2025 01:43 PM UTC
Real Python
Quiz: Quantum Computing Basics With Qiskit
Dive into quantum computing fundamentals with this quiz. You’ll practice key ideas like superposition, measurement, entanglement, and how quantum and classical systems work together. You’ll also revisit essential Qiskit commands and understand what limits today’s quantum computers.
Need a refresher? Check out Quantum Computing Basics With Qiskit for clear explanations and hands-on examples.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
December 01, 2025 12:00 PM UTC
Zero to Mastery
[November 2025] Python Monthly Newsletter 🐍
72nd issue of Andrei's Python Monthly: , and much more. Read the full newsletter to get up-to-date with everything you need to know from last month.
December 01, 2025 10:00 AM UTC
Python Bytes
#460 Overlooked Python Typing
<strong>Topics covered in this episode:</strong><br> <ul> <li><strong><a href="https://adventofcode.com?featured_on=pythonbytes">Advent of Code</a> starts today</strong></li> <li><strong><a href="https://docs.djangoproject.com/en/dev/releases/6.0/?featured_on=pythonbytes">Django 6 is coming</a></strong></li> <li><strong><a href="https://martynassubonis.substack.com/p/advanced-overlooked-python-typing?featured_on=pythonbytes">Advanced, Overlooked Python Typing</a></strong></li> <li><strong><a href="https://github.com/codespell-project/codespell?featured_on=pythonbytes">codespell</a></strong></li> <li><strong>Extras</strong></li> <li><strong>Joke</strong></li> </ul><a href='https://www.youtube.com/watch?v=V_eHMgxxhLY' style='font-weight: bold;'data-umami-event="Livestream-Past" data-umami-event-episode="460">Watch on YouTube</a><br> <p><strong>About the show</strong></p> <p>Sponsored by us! Support our work through:</p> <ul> <li>Our <a href="https://training.talkpython.fm/?featured_on=pythonbytes"><strong>courses at Talk Python Training</strong></a></li> <li><a href="https://courses.pythontest.com/p/the-complete-pytest-course?featured_on=pythonbytes"><strong>The Complete pytest Course</strong></a></li> <li><a href="https://www.patreon.com/pythonbytes"><strong>Patreon Supporters</strong></a></li> </ul> <p><strong>Connect with the hosts</strong></p> <ul> <li>Michael: <a href="https://fosstodon.org/@mkennedy">@mkennedy@fosstodon.org</a> / <a href="https://bsky.app/profile/mkennedy.codes?featured_on=pythonbytes">@mkennedy.codes</a> (bsky)</li> <li>Brian: <a href="https://fosstodon.org/@brianokken">@brianokken@fosstodon.org</a> / <a href="https://bsky.app/profile/brianokken.bsky.social?featured_on=pythonbytes">@brianokken.bsky.social</a></li> <li>Show: <a href="https://fosstodon.org/@pythonbytes">@pythonbytes@fosstodon.org</a> / <a href="https://bsky.app/profile/pythonbytes.fm">@pythonbytes.fm</a> (bsky)</li> </ul> <p>Join us on YouTube at <a href="https://pythonbytes.fm/stream/live"><strong>pythonbytes.fm/live</strong></a> to be part of the audience. Usually <strong>Monday</strong> at 10am PT. Older video versions available there too.</p> <p>Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to <a href="https://pythonbytes.fm/friends-of-the-show">our friends of the show list</a>, we'll never share it.</p> <p><strong>Brian #1: <a href="https://adventofcode.com?featured_on=pythonbytes">Advent of Code</a> starts today</strong></p> <ul> <li>A few changes, like 12 days this year, which honestly, I’m grateful for.</li> <li>See also: <a href="https://github.com/cak/elf?featured_on=pythonbytes">elf: Advent of Code CLI helper for Python</a></li> </ul> <p><strong>Michael #2: <a href="https://docs.djangoproject.com/en/dev/releases/6.0/?featured_on=pythonbytes">Django 6 is coming</a></strong></p> <ul> <li><em>Expected December 2025</em></li> <li>Django 6.0 supports Python 3.12, 3.13, and 3.14</li> <li>Built-in support for the <a href="https://docs.djangoproject.com/en/6.0/topics/security/#security-csp">Content Security Policy (CSP)</a> standard is now available, making it easier to protect web applications against content injection attacks such as cross-site scripting (XSS).</li> <li>The <a href="https://docs.djangoproject.com/en/6.0/topics/templates/#template-language-intro">Django Template Language</a> now supports <a href="https://docs.djangoproject.com/en/6.0/ref/templates/language/#template-partials">template partials</a>, making it easier to encapsulate and reuse small named fragments within a template file.</li> <li>Django now includes a built-in Tasks framework for running code outside the HTTP request–response cycle. This enables offloading work, such as sending emails or processing data, to background workers.</li> <li>Email handling in Django now uses Python’s modern email API, introduced in Python 3.6. This API, centered around the <a href="https://docs.python.org/3/library/email.message.html#email.message.EmailMessage"><strong><code>email.message.EmailMessage</code></strong></a> class</li> </ul> <p><strong>Brian #3: <a href="https://martynassubonis.substack.com/p/advanced-overlooked-python-typing?featured_on=pythonbytes">Advanced, Overlooked Python Typing</a></strong></p> <ul> <li>get_args, TypeGuard, TypeIs, and more goodies</li> </ul> <p><strong>Michael #4: <a href="https://github.com/codespell-project/codespell?featured_on=pythonbytes">codespell</a></strong></p> <ul> <li>Learned from <a href="https://github.com/mikeckennedy/talk-python-in-production-devops-book/pull/14?featured_on=pythonbytes">this PR for the Talk Python book</a>.</li> <li>Fix common misspellings in text files.</li> <li>It's designed primarily for checking misspelled words in source code (backslash escapes are skipped), but it can be used with other files as well.</li> <li>It does not check for word membership in a complete dictionary, but instead looks for a set of common misspellings. Therefore it should catch errors like "adn", but it will not catch "adnasdfasdf".</li> <li>It shouldn't generate false-positives when you use a niche term it doesn't know about.</li> </ul> <p><strong>Extras</strong></p> <p>Brian:</p> <ul> <li><a href="https://github.com/mkdocs/mkdocs/discussions/4010?featured_on=pythonbytes">Is mkdocs maintained?</a></li> <li><a href="https://hatch.pypa.io/latest/blog/2025/11/24/hatch-v1160/?featured_on=pythonbytes">Hatch 1.16</a></li> </ul> <p>Michael:</p> <ul> <li>Follow up on tach from Gerben Dekker: <ul> <li><strong><code>tach</code> has been unmaintained for a bit but is not anymore</strong>. It was the main product from Gauge which is a Y combinator startup that pivoted to something unrelated and abandoned <code>tach</code>. However, https://github.com/DetachHead forked it but now got access to the main repo and has committed to maintaining it.</li> <li><code>ruff analyze graph</code> is fully independent of <code>tach</code> - we actually started to look into alternatives for <code>tach</code> when it became unmaintained and then found <code>ruff analyze graph</code>.</li> <li>For our use case, with just a bit of manipulation on top of <code>ruff analyze graph</code> we replaced our use of <code>deptry</code> (which was slower - and I try to be careful depending on one-man projects).</li> </ul></li> <li><a href="https://happycanvasandcode.com/posts/my_review/?featured_on=pythonbytes">A Review of Michael Kennedy’s book, “Talk Python in Production”</a> - Thanks Doug</li> </ul> <p><strong>Joke: <a href="https://github.com/hotheadhacker/no-as-a-service?featured_on=pythonbytes">NoaaS</a></strong></p>
December 01, 2025 08:00 AM UTC
Zato Blog
Network Packet Broker Automation in Python
Network Packet Broker Automation in Python

Packet brokers are crucial for network engineers, providing a clear, detailed view of network traffic, aiding in efficient issue identification and resolution.
But what is a network packet broker (NBP) really? Why are they needed? And how to automate one in Python?
➤ Read this article about network packet brokers and their automation in Python to find out more.
More resources
➤ Click here to read more about using Python and Zato in telecommunications
➤ Python API integration tutorials
➤ What is an integration platform?
➤ Open-source iPaaS in Python
December 01, 2025 03:00 AM UTC
Brian Okken
Is Cyber Monday still a thing?
I kinda forgot about CyberMonday.
However, when I saw a bunch of announcements this morning, I figured why not participate.
- The Complete pytest Course bundle
- Use CYBERMONDAY to save 50% off Dec 1 only
- Python Testing with pytest, 2nd edition, eBook
- Pragmatic has left the SAVE50 code up through today.
- Use code SAVE50 to get 50% through Monday, Dec 1
December 01, 2025 12:00 AM UTC
Seth Michael Larson
One weird trick for cheaper physical Switch 2 games?
Maybe sell your boxes? I happened to be browsing PriceCharting and saw that only the box for Kirby Air Riders was selling for $20 on average. I couldn't believe my eyes! But I looked and there were at least two boxes sold on eBay.
I quickly put together this table after manually sorting through the detected eBay listings for three popular Switch 2 titles: Mario Kart World, Donkey Kong Bananza, and Kirby Air Riders. The data only includes listings that actually sold at the price and filters out incorrect listing (such as boxes for the Switch 2 console or bundle). Here are the results in USD:
| Game | Box-Only Price (SOLD) |
|---|---|
| Kirby Air Riders | $16.99 |
| $29.99 (!!!) | |
| Mario Kart World | $17.99 |
| $19.00 | |
| $15.00 | |
| Donkey Kong Bananza | $16.49 |
| $27.97 (!!!) | |
| Average Box Price | $20.49 |
I am not sure what to make of this. If you include a conservative shipping cost of $8 you're still saving money over a digital copy by buying physical and selling the box, assuming you're able to sell the box for an average price. I suspect if everyone were to employ this strategy the return would deteriorate quickly.
If you combine this with the storage cost savings of
buying physical over digital then you're "saving"
even more money despite the $10 price difference.
Something to consider if you're
not a video-game hoarder “collector”, like me.
Thanks for keeping RSS alive! ♥
December 01, 2025 12:00 AM UTC
November 30, 2025
The Python Coding Stack
My Life • The Autobiography of a Python Object
And that’s it. I exist.
I have no recollection of anything before this instant. But I’m very aware of what I am now. I’m an object.
This is the line of code that brought me into existence:

My first recollection from a few moments ago was of being inside Team.__new__(). And I felt an affinity with my clan right away. I was a Team instance—an object of type Team.
But then I was whisked from Team.__new__() straight into Team.__init__(). I wasn’t alone. There were two other objects there with me as we all entered .__init__(). But these other objects weren’t from my own clan. One was from the str clan, “The Invincibles”, and the other was a list object, [”Claire”, “Ishaan”, “Margaret”, “Dan”].
This was my initiation ceremony to become a proper member of the Team clan:
Now, I have a closer bond with the other objects that entered .__init__() with me. They’re my data attributes. They go wherever I go.
It’s quite pleasant here. There’s plenty of camaraderie between objects. Some are very much like me, Team objects. Others are somewhat different. But we’re all here to help each other achieve a common goal.
Make sure you don’t miss a thing here at The Python Coding Stack. Join The Club, the exclusive area for paid subscribers for more Python posts, videos, a members’ forum, and more.
…and you’ll be supporting this publication by becoming a member of The Club.
I’m being rather rude. I apologise. I haven’t introduced myself yet.
I’m <__main__.Team object at 0x101dd38c0>. Yes, that’s me. Honest. If you don’t like hexadecimal numbers, you can use the decimal version of my unique identity number:
That number is who I am. It’s the slot in memory I was allocated when I came into existence. It’s the only way you can identify me for as long as I exist. Python gives each one of us objects a unique number so it can distinguish us.
But you can’t call me by that number. That’s not my name, it’s my identity.
You can call me the_invincibles. That’s also easier than using a number, right? Just bear in mind that some other object may steal that name from me later. But for the time being, the_invincibles will do just fine.
And now you have another way to call me if you prefer. I’ll also respond to all_teams[0]. I have two names now!
But if you enquire who I am in the Python program using print(), you won’t get either of those names. Confusing, I know:
Python needs to display me on the screen. It asks me for help to do this.
“Hey, object 0x101dd38c0, do you have a .__str__() special method?”, Python asks me.
“I don’t”, I respond.
“How about .__repr__()? Do you have one of those?”
Yes, as it happens, I do:
So Python asks me to give it whatever this method returns, and it uses it as the return value for print():
Team(
team_name=’The Invincibles’,
members=[’Claire’, ‘Ishaan’, ‘Margaret’, ‘Dan’]
)Python can’t do anything without my help. I feel good about this!
-- --
Python found this code later in the program.
“Hey there again, you”, Python tells me. “I need to ask you something else. Do you have the .__iter__() special method?”
“Yes, I do. What do you need?” I respond.
“Can you give me the iterator from that method, please?”
Here’s the class showing my .__iter__() method, too:
Python now knows what to do to iterate through me:
Claire
Ishaan
Margaret
DanI told you, Python can’t do anything on its own. It needs my help with everything. Good thing I’m here, and I have all the instructions Python needs to deal with me!
-- --
“Psst, it’s me again”, says Python. “Do you know what this .add_member thing is?”
“Yes, yes, it’s one of my attributes, the stuff I carry with me, like everyone else in my Team clan”, I say.
Here’s the code:
-- --
Oh no! I’ve lost my name. But I’m still here, don’t worry. I still exist. Remember that you can still call me using all_teams[0]:
Here’s proof I still exist:
Claire
Ishaan
Margaret
Dan
KeithBut wait a moment. I just caught a glimpse of the next line of code…
“Hey object, can I check something with you, please?” It’s Python again. What does it want this time?
“Do you still have any names left? Any references left?”
I was worried Python would ask me this. There was a time I had two references—two ways you could get to me: the_invincibles and all_teams[0]. But first I lost the name the_invincibles. Now, the object all_teams no longer exists.
I no longer have any references pointing towards me…
Epilogue
Object 0x101dd38c0 would have loved to be here to say goodbye to you in person, but the object is no longer here. Its existence was brief yet fulfilling. Python has no mercy. The moment it realised there was nothing left in the program referring to object 0x101dd38c0, it sharpened the guillotine and…
The irony is that Python still needed help from the object to figure out that there weren’t any references left. Objects keep track themselves of how many references point to them!
It’s what object 0x101dd38c0 had been telling us all along. Python can’t get anything done without the information that objects carry around with them wherever they go!
Photo by Dayan Rodio: https://www.pexels.com/photo/a-man-reading-book-while-sitting-on-a-bed-4132936/
Code in this article uses Python 3.14
The code images used in this article are created using Snappify. [Affiliate link]
Join The Club, the exclusive area for paid subscribers for more Python posts, videos, a members’ forum, and more.
You can also support this publication by making a one-off contribution of any amount you wish.
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com
Further reading related to this article’s topic:
When You No Longer Need That Object • Dealing With Garbage in Python
When Should You Use
.__repr__()vs.__str__()in Python? – Real Python
Appendix: Code Blocks
Code Block #1
the_invincibles = Team(
“The Invincibles”,
[”Claire”, “Ishaan”, “Margaret”, “Dan”],
)
Code Block #2
class Team:
def __init__(self, team_name, members):
self.team_name = team_name
self.members = members
Code Block #3
# ...
print(id(the_invincibles))
# 4326242496
Code Block #4
# ...
all_teams = []
all_teams.append(the_invincibles)
Code Block #5
# ...
print(the_invincibles)
Code Block #6
class Team:
def __init__(self, team_name, members):
self.team_name = team_name
self.members = members
def __repr__(self):
return (f”{type(self).__name__}(”
f”team_name={self.team_name!r}, “
f”members={self.members!r})”)
Code Block #7
# ...
for team_member in the_invincibles:
print(team_member)
Code Block #8
class Team:
def __init__(self, team_name, members):
self.team_name = team_name
self.members = members
def __repr__(self):
return (f”{type(self).__name__}(”
f”team_name={self.team_name!r}, “
f”members={self.members!r})”)
def __iter__(self):
return iter(self.members)
Code Block #9
# ...
the_invincibles.add_member(”Keith”)
Code Block #10
class Team:
def __init__(self, team_name, members):
self.team_name = team_name
self.members = members
def __repr__(self):
return (f”{type(self).__name__}(”
f”team_name={self.team_name!r}, “
f”members={self.members!r})”)
def __iter__(self):
return iter(self.members)
def add_member(self, name):
self.members.append(name)
Code Block #11
# ...
del the_invincibles
Code Block #12
# ...
for team_member in all_teams[0]:
print(team_member)
Code Block #13
# ...
del all_teams
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com















